/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
 *
 */

import { FileSet, hvigorCore } from '@ohos/hvigor';
import fse from 'fs-extra';
import path from 'path';

import { FileUtil } from '../utils/file-util.js';

import { BaseSign } from './base/base-sign.js';
import { TaskNames } from './common/task-names.js';
import { LegacyPackageHap } from './legacy-tasks/legacy-package-hap';
import { ModuleTaskService } from './service/module-task-service.js';
import { TargetTaskService } from './service/target-task-service.js';
import { SignModel } from './sign/command-builder-impl/sign-model.js';
import { PackageHap } from './package-hap.js';
import { CommonConst } from '../const/common-const.js';

/**
 * Sign hap
 *
 * @since 2022/1/10
 */
export class SignHap extends BaseSign {
  /**
   * 签名入参对象集合
   *
   * @private
   */
  private readonly signModelList: SignModel[] = [];

  constructor(targetService: TargetTaskService) {
    super(targetService, TaskNames.CommonTask.SIGN_HAP);
    this.initSignModelData();
  }

  taskShouldDo(): boolean {
    return !(this.targetService.getBuildOption().packOptions?.buildAppSkipSignHap && hvigorCore.isCommandEntryTask(TaskNames.CommonHookTask.ASSEMBLE_APP.name));
  }

  declareInputFiles(): FileSet {
    const inputFiles = super.declareInputFiles();
    for (const signModel of this.signModelList) {
      const signInputFilePath = signModel.getInputFilePath();
      if (fse.existsSync(signInputFilePath)) {
        inputFiles.addEntry(signInputFilePath, { isDirectory: false });
      }
    }
    return inputFiles;
  }

  declareOutputFiles(): FileSet {
    const outputFiles = super.declareOutputFiles();
    for (const signModel of this.signModelList) {
      const signOutputFilePath = signModel.getOutPutFilePath();
      if (signOutputFilePath) {
        outputFiles.addEntry(signOutputFilePath, { isDirectory: false });
      }
    }
    return outputFiles;
  }

  protected async doTaskAction() {
    for (const signModel of this.signModelList) {
      // 当任务非增量时，先删除上一次已签名的输出文件
      FileUtil.deleteFile(signModel.getOutPutFilePath());
      if (!hvigorCore.getParameter().getProperty(CommonConst.ENABLE_SIGN_TASK)) {
        return;
      }
      await this.signUtil.sign(signModel, this.durationEvent);
    }
  }

  initTaskDepends() {
    this.declareDepends(this.isFaMode ? LegacyPackageHap.name : PackageHap.name);
  }

  /**
   * 初始化签名入参对象集合
   *
   * @private
   */
  private initSignModelData(): void {
    const relatedEntryModules = this.service.getRelatedEntryModules();
    const moduleType = this.service.getModuleModel().getModuleType();
    if (ModuleTaskService.checkEntryModules(moduleType, relatedEntryModules)) {
      for (const entryName of relatedEntryModules!) {
        this.addSignModel(entryName);
      }
    } else {
      this.addSignModel('');
    }
  }

  /**
   * 根据传入entryName，添加signModel签名入参对象
   *
   * @param entryName
   * @private
   */
  private addSignModel(entryName: string): void {
    if (this.targetData.isSingleDeviceTypeTarget()) {
      const outputFileName = this.targetData.getModuleTargetOutputFileName(entryName, false);
      const inputFile = path.resolve(this.pathInfo.getModuleBuildOutputPath(), outputFileName);
      const outputFile = path.resolve(this.pathInfo.getModuleBuildOutputPath(), this.targetData.getModuleTargetOutputFileName(entryName, true));
      this.signModelList.push(new SignModel(this.signType, inputFile, outputFile));
    } else {
      this.targetData.getTargetDeviceTypeClasses().forEach((deviceType: string) => {
        const inputFileName = this.targetData.getModuleTargetOutputFileName(entryName, false, undefined, deviceType);
        const inputFile = path.resolve(this.pathInfo.getModuleBuildOutputPath(), inputFileName);

        const outputFileName = this.targetData.getModuleTargetOutputFileName(entryName, true, undefined, deviceType);
        const outputFile = path.resolve(this.pathInfo.getModuleBuildOutputPath(), outputFileName);
        this.signModelList.push(new SignModel(this.signType, inputFile, outputFile));
      });
    }
  }
}
